﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Soft.Data
{

    /// <summary>
    /// 控制码
    /// </summary>
    public struct ControlCode : IEquatable<ControlCode>, IFunctionCode
    {

        public ControlCode(uint number)
        {
            if (number >= 9999999U)
            {
                throw new ArgumentOutOfRangeException("", "数值范围必须是：0 - " + 9999999U.ToString());
            }
            this.Number = number;
        }


        /// <summary>
        /// 控制号
        /// </summary>
        private uint Number { get; set; }


        /// <summary>
        /// 控制码
        /// </summary>
        public string Code
        {
            get
            {
                return "CTRL" + this.Number.ToString("0000000");
            }
        }


        public override string ToString()
        {
            return this.Code;
        }


        /// <summary>
        /// 判断是否是控制码
        /// </summary>
        /// <param name="controlCode"></param>
        /// <returns></returns>
        public static bool IsControlCode(string controlCode)
        {
            return ToolsClass.RegexTest("^CTRL\\d{7}", controlCode.ToUpper());
        }


        /// <summary>
        /// 将字符串解析为控制码
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static ControlCode Parse(string s)
        {
            if (ControlCode.IsControlCode(s))
            {
                return new ControlCode(s.Substring(4).ConvertTo(0U, true));
            }
            throw new FormatException("Wrong format.");
        }


        public override bool Equals(object obj)
        {
            return obj != null && obj is ControlCode && this.Equals((ControlCode)obj);
        }


        public bool Equals(ControlCode other)
        {
            return this.Number == other.Number;
        }


        public override int GetHashCode()
        {
            return this.Number.GetHashCode();
        }


        /// <summary>
        /// 判断两个控制码是否相等
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator ==(ControlCode a, ControlCode b)
        {
            return a.Equals(b);
        }


       /// <summary>
       /// 判断两个控制码不等
       /// </summary>
       /// <param name="a"></param>
       /// <param name="b"></param>
       /// <returns></returns>
        public static bool operator !=(ControlCode a, ControlCode b)
        {
            return !a.Equals(b);
        }


        public static implicit operator ControlCode(string value)
        {
            return ControlCode.Parse(value);
        }


        /// <summary>
        /// 控制器标识符
        /// </summary>
        private const string CODE_SIGN = "CTRL";
        

        /// <summary>
        /// 最大的控制号
        /// </summary>
        private const uint MAX_NUMBER = 9999999U;


        /// <summary>
        /// 输出格式  补O对齐
        /// </summary>        
        private const string OUTPUT_FORMAT = "0000000";


    }
}
